op {
  graph_op_name: "SparseSoftmax"
  in_arg {
    name: "sp_indices"
    description: <<END
2-D.  `NNZ x R` matrix with the indices of non-empty values in a
SparseTensor, in canonical ordering.
END
  }
  in_arg {
    name: "sp_values"
    description: <<END
1-D.  `NNZ` non-empty values corresponding to `sp_indices`.
END
  }
  in_arg {
    name: "sp_shape"
    description: <<END
1-D.  Shape of the input SparseTensor.
END
  }
  out_arg {
    name: "output"
    description: <<END
1-D.  The `NNZ` values for the result `SparseTensor`.
END
  }
  summary: "Applies softmax to a batched N-D `SparseTensor`."
  description: <<END
The inputs represent an N-D SparseTensor  with logical shape `[..., B, C]`
(where `N >= 2`), and with indices sorted in the canonical lexicographic order.

This op is equivalent to applying the normal `tf.nn.softmax()` to each innermost
logical submatrix with shape `[B, C]`, but with the catch that *the implicitly
zero elements do not participate*.  Specifically, the algorithm is equivalent
to the following:

  (1) Applies `tf.nn.softmax()` to a densified view of each innermost submatrix
      with shape `[B, C]`, along the size-C dimension;
  (2) Masks out the original implicitly-zero locations;
  (3) Renormalizes the remaining elements.

Hence, the `SparseTensor` result has exactly the same non-zero indices and
shape.
END
}
